<?php
/**
 * 分页类
 *
 * [Code]
 * $url = "";
 * $page = 1;
 * $totalPage = 8;
 * $pageShow = 10;
 * $terms = array('first'=>'首页','pre'=>'上一页','next'=>'下一页','last'=>'尾页');
 * $h = App::h('Pagination');
 * $h->init($url, $pageId, $pageCount, $pageShow, $terms);
 * $dom = $h->display();
 * [/Code]
 *
 * @version $Id: Pagination.php 150 2013-10-16 09:05:26Z linsir123 $
 * @package Helper
 */
class HelperPagination
{
	/**
	 * 链接中页码的替换关键字
	 */
	const URL_P = "__PAGE__";

	/**
	 * 链接中描述的替换关键字
	 */
	const URL_TERM = "__TERM__";

	/**
	 * 链接中页码的样式
	 *
	 * @var int
	 */
	public $urlPStyle = 0;

	/**
	 * 分页的链接格式(需要预留%d以供填充)
	 *
	 * @var string
	 */
	public $url;

	/**
	 * 当前页码
	 *
	 * @var int
	 */
	public $pageId;

	/**
	 * 总页数
	 *
	 * @var int
	 */
	public $pageCount;

	/**
	 * 显示的分页个数
	 *
	 * @var int
	 */
	public $pageShow;

	/**
	 * 显示的分页文案
	 *
	 * @var array
	 */
	public $terms;

	/**
	 * 链接HTML格式化
	 *
	 * @var string
	 */
	public $aFormat;

	/**
	 * 构造函数
	 *
	 * @param string $url 分页的链接格式(需要预留%d以供填充)
	 * @param int $pageId 当前页码
	 * @param int $pageCount 总页数
	 * @param int $pageShow 显示的分页个数
	 * @param array $terms 显示的分页文案
	 */
	public function init($url, $pageId, $pageCount, $pageShow = 10, $terms = array())
	{
		if ($pageId < 1)
			$pageId = 1;
		elseif ($pageId > $pageCount)
			$pageId = $pageCount;

		if (empty($terms))
			$terms = array(
				'first' => '首页',
				'pre' => '上一页',
				'next' => '下一页',
				'last' => '尾页'
			);

		///
		$this->url = $url;
		$this->pageId = $pageId;
		$this->pageCount = $pageCount;
		$this->pageShow = $pageShow;
		$this->terms = $terms;
	}

	/**
	 * 自定义HTML格式化
	 *
	 * @param string $format
	 */
	public function setAformat($format)
	{
		$this->aFormat = $format;
	}

	/**
	 * 自定义链接中页码的替换方式
	 *
	 * @param int $style 0以%d方式; 1以字符方式进行替换
	 */
	public function setUrlPStyle($style = 0)
	{
		$this->urlPStyle = $style;
	}

	/**
	 * 取得分类数据,用于html的自定义
	 */
	public function getData()
	{
		if ($this->pageCount <= 1)
			return false;

		$data = array(
			'first' => null,
			'pre' => null,
			'num' => array(
				'pre' => false,
				'list' => array(),
				'next' => false
			),
			'next' => null,
			'last' => null,
		);
		list($startPage, $endPage) = $this->_getRange();

		///
		if ($this->pageId > 1) {
			$data['first'] = sprintf($this->url, 1);
			$data['pre'] = sprintf($this->url, $this->pageId - 1);
		}
		$data['num']['pre'] = $startPage >= 2 && $this->pageShow < $this->pageCount;
		for ($i = $startPage; $i <= $endPage; $i ++) {
			if ($i == $this->pageId)
				$data['num']['list'][$i] = array($i);
			else
				$data['num']['list'][$i] = sprintf($this->url, $i);
		}
		$data['num']['next'] = $endPage < $this->pageCount;
		if ($this->pageId < $this->pageCount) {
			$data['next'] = sprintf($this->url, $this->pageId + 1);
			$data['last'] = sprintf($this->url, $this->pageCount);
		}

		return $data;
	}

	/**
	 * 以分页，显示分页内容
	 */
	public function display()
	{
		if ($this->pageCount <= 1)
			return false;

		$nav = '';
		list($startPage, $endPage) = $this->_getRange();

		///
		if ($this->pageId > 1) {
			if (isset($this->terms['first']))
				$nav .= $this->_a(1, $this->terms['first']);

			$nav .= $this->_a($this->pageId - 1, $this->terms['pre']);
		}
		if ($startPage >= 2 && $this->pageShow < $this->pageCount)
			$nav .= "<span><span>...</span></span>";

		///
		for ($i = $startPage; $i <= $endPage; $i ++) {
			if ($i == $this->pageId)
				$nav .= "<span class=\"current\"><span>$i</span></span>";
			else
				$nav .= $this->_a($i, $i);
		}

		///
		if ($endPage < $this->pageCount)
			$nav .= "<span><span>...</span></span>";

		if ($this->pageId < $this->pageCount) {
			$nav .= $this->_a($this->pageId + 1, $this->terms['next']);
			if (isset($this->terms['last']))
				$nav .= $this->_a($this->pageCount, $this->terms['last']);
		}

		return "<div id=\"page_nav\" class=\"mod_page\">{$nav}</div>";
	}


	/// 以下为私有方法 ///


	/**
	 * 取得区间上下限
	 */
	private function _getRange()
	{
		$pageShow2 = $this->pageShow - 1;
		$halfStart = floor($pageShow2 / 2);
		$halfEnd = ceil($pageShow2 / 2);
		$startPage = $this->pageId - $halfStart;
		$endPage = $this->pageId + $halfEnd;

		///
		if ($startPage <= 0)
			$startPage = 1;

		if (($endPage - $startPage) != $pageShow2)
			$endPage = $startPage + $pageShow2;

		if ($endPage > $this->pageCount) {
			$startPage = $this->pageCount - $pageShow2;
			$endPage = $this->pageCount;
		}

		if ($startPage <= 0)
			$startPage = 1;

		return array($startPage, $endPage);
	}

	/**
	 * 格式化链接HTML
	 *
	 * @param int $pageId 页码
	 * @param string $term 显示内容
	 *
	 * @return string
	 */
	private function _a($pageId, $term)
	{
		if (empty($this->aFormat))
			$dom = "<a href=\"" . $this->url . "\"><span>" .
				($this->urlPStyle == 0 ? "%s" : self::URL_TERM) .
				"</span></a>";
		else
			$dom = $this->aFormat;

		///
		if ($this->urlPStyle == 0)
			return sprintf($dom, $pageId, $term);

		///
		$dom = str_replace(self::URL_TERM, $term, $dom);
		$dom = str_replace(self::URL_P, $pageId, $dom);

		return $dom;
	}
}
